package chapterSystem.client.interfaceDrawing.activities;

import chapterSystem.client.ChapterSystemService;
import chapterSystem.client.callbacks.LoggCallback;
import chapterSystem.client.entities.Pair;
import chapterSystem.client.entities.UnitInfo;
import chapterSystem.client.model.entitiesInt.Brother;
import chapterSystem.client.model.entitiesInt.Unit;
import chapterSystem.client.model.enums.ActivityType;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Svetlana Zemlyanskaya(svetazem@yandex-team.ru)
 * Date: 4/8/12
 */
public class UnitActivity extends Activity {
    Map<String, Unit> allUnits;

    public UnitActivity(final Brother brother) {
        super(brother, ActivityType.UNIT);
        allUnits = new HashMap<String, Unit>();
    }

    @Override
    public void drawActivity(final StackLayoutPanel workArea) {
        ChapterSystemService.App.getInstance().getUnitInfo(brother.getId(), new UnitCallback(workArea));
        ChapterSystemService.App.getInstance().addLog(brother.getId(), id, "Review units",
                new LoggCallback());
    }

    private class UnitCallback implements AsyncCallback<UnitInfo> {
        final private StackLayoutPanel workArea;

        private UnitCallback(StackLayoutPanel workArea) {
            this.workArea = workArea;
        }


        @Override
        public void onFailure(Throwable caught) {
            workArea.clear();
            workArea.add(new HTML(), new HTML("Failed to connect to server"), 4);
        }

        @Override
        public void onSuccess(UnitInfo result) {
            workArea.clear();
            fillAllUnits(result.getRoot());

            workArea.add(buildUnit(result.getCurrent(), false), new HTML("My Unit"), 4);

            final VerticalPanel submission = new VerticalPanel();
            submission.setBorderWidth(3);
            submission.setWidth("100%");

            for (final Unit unit : result.getSubmission()) {
                final VerticalPanel panel = new VerticalPanel();
                panel.setBorderWidth(3);
                panel.setWidth("100%");

                final Button writeOrderButton = new Button("Write order to unit's commander");
                writeOrderButton.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        new WriteBattleOrderActivity(brother, ActivityType.WRITE_ORDER, UnitActivity.this,
                                new Pair<String, Integer>(unit.getCommander().getName(), unit.getCommander().getId())).drawActivity(workArea);
                    }
                });
                if (unit.getCommander().getId() == brother.getId()) {
                    writeOrderButton.setEnabled(false);
                }

                panel.add(buildUnit(unit, true));
                panel.add(writeOrderButton);
                panel.setCellHorizontalAlignment(writeOrderButton, HasAlignment.ALIGN_CENTER);

                submission.add(panel);
            }
            workArea.add(new ScrollPanel(submission), new HTML("Submission"), 4);
            workArea.add(createMapPanel(result.getRoot()), new HTML("All Units"), 4);
        }

        private void fillAllUnits(final Unit root) {
            allUnits.put(root.getName(), root);
            final List<Unit> units = root.getSubunits();
            for(final Unit unit : units) {
                fillAllUnits(unit);
            }
        }

        private FormPanel buildUnit(final Unit unit, final boolean edit) {
            FormPanel panel = new FormPanel();
            panel.setWidth("100%");

            FlexTable table = new FlexTable();
            table.setStyleName("unit_panel_style", true);

            table.setText(0, 0, "Name: ");
            table.setText(1, 0, "Commander: ");
            table.setText(2, 0, "Brothers: ");
            table.setText(3, 0, "Type: ");
            table.setText(4, 0, "Outpost: ");
            table.setText(5, 0, "Location: ");

            table.setText(0, 1, unit.getName());
            table.setText(1, 1, unit.getCommander().getName());
            final CellList<String> brothers = fillBrotherList(unit.getAllBrothers(), edit);
            brothers.setStyleName("empty_style");
            table.setWidget(2, 1, brothers);
            table.setText(3, 1, unit.getUnitType().toString());
            table.setText(4, 1, unit.getBaseOutpost());
            table.setText(5, 1, unit.getCurrentLocation());

            panel.add(table);
            return panel;

        }

        private CellList<String> fillBrotherList(final List<Brother> brothers, final boolean edit) {
            final CellList<String> cellList = new CellList<String>(new TextCell());
            final List<String> brothersName = new ArrayList<String>();

            for (final Brother brother : brothers) {
                brothersName.add(brother.getName());
//                brothersName.add(new HTML("<b style=\"color:#000000; background:#ffffff; \">" + brother.getName() + "</b>"));
//                lb.addC addItem(brother.getName());
            }

            if(edit) {
                addClickEdit(cellList, allUnits);
            }
            cellList.setStyleName("empty_style");
            cellList.setRowCount(brothersName.size());
            cellList.setRowData(brothersName);
            return cellList;
        }

        private void addClickEdit(final CellList<String> cellList, final Map<String, Unit> units) {
            final SingleSelectionModel<String> selectionModel = new SingleSelectionModel<String>();
            cellList.setSelectionModel(selectionModel);
            selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
                public void onSelectionChange(SelectionChangeEvent event) {
                    String selected = selectionModel.getSelectedObject();
                    if (selected != null) {
                         new EditBrotherActivity(brother, ActivityType.EDIT_BROTHER, new UnitActivity(brother),
                                 selected, units).drawActivity(workArea);
                        System.out.println("You selected: " + selected);
                    }
                }
            });
        }

        private HorizontalPanel createMapPanel(final Unit root) {
            final HorizontalPanel panel = new HorizontalPanel();
            panel.setWidth("100%");
            final Panel treePanel = new FormPanel();
            treePanel.setStyleName("empty_style");
            treePanel.setWidth("100%");
            treePanel.add(buildTree(root));
            panel.setStyleName("empty_style");
            panel.add(treePanel);
//            panel.add(buildUnit(root));
            return panel;
        }

        private Tree buildTree(Unit root) {
            Tree t = new Tree();
            t.setStyleName("empty_style");
            final TreeItem item = getTreeItem(root);
            item.setStyleName("empty_style");
            item.setHTML("<h style=\"background:#ffffff; color:#000000\">" + root.getName() + "</h>");
            t.addItem(item);
            t.setStyleName("empty_style");
            t.setStylePrimaryName("empty_style");
            return t;
        }

        private TreeItem getTreeItem(final Unit root) {
            TreeItem item = new TreeItem(root.getName());

            item.setStyleName("empty_style");
            for (final Unit unit : root.getSubunits()) {
                final TreeItem newItem = getTreeItem(unit);
                newItem.setStyleName("empty_style");
                newItem.setHTML("<h style=\"background:#ffffff; color:#000000\">" + unit.getName() + "</h>");
                item.addItem(newItem);
            }
            return item;
        }
    }
}
